import React from 'react'
import renderer from 'react-test-renderer'
import { mount } from 'enzyme'
import Loading from 'react-aaui/es/loading'

import asyncComponent from 'components/asyncComponent'
import Hello from './__mocks__/Hello'

jest.mock('react-aaui/es/loading', () => ({
  show: jest.fn(() => 'show'),
  hide: jest.fn(() => 'hide'),
}))

const setup = (props = {}) => {
  const Component = asyncComponent(() =>
    import('./__mocks__/Hello').then(module => module.default),
  )

  if (props.staticComponent) {
    Component.Component = props.staticComponent
  }

  const wrapper = mount(<Component />)

  return {
    Component,
    wrapper,
  }
}

it('should render without errors', () => {
  const { wrapper } = setup()

  expect(wrapper).toBeTruthy()
})

it("should render right thing and don't change unexpected", () => {
  const { Component } = setup()
  const tree = renderer.create(<Component />).toJSON()

  expect(tree).toMatchSnapshot()
})

it('`AsyncComponent.Component`', () => {
  const { Component } = setup({
    staticComponent: Hello,
  })

  expect(renderer.create(<Component />).toJSON()).toMatchSnapshot()
})

it('set `isLoading` state as false', () => {
  const { wrapper } = setup()

  wrapper.setState({
    Component: null,
    isLoading: false,
  })

  expect(wrapper.html()).toMatchSnapshot()
})

it('should call Loading.hide() when unmount', () => {
  Loading.hide = jest.fn()
  const { wrapper } = setup()

  expect(Loading.hide).toHaveBeenCalledTimes(0)

  wrapper.unmount()

  expect(Loading.hide).toHaveBeenCalledTimes(1)
})
